#include "minesweeper.h"

using namespace std;

void mine_ui_init(char mine_ui[][COL])
{
#if 0
    // 【必会点】基本实现
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COL; j++)
        {
            mine_ui[i][j] = '*';
        }   
    }
#endif
    /*
    C 语言内存设置函数，需要提供给函数的参数是目标内存首地址，
    每一个字节对应的数据内容，和总计设置内存的字节数。
    【家政函数】
        告知家政公司你的地址
        打扫的标准
        面积
    【内存操作，后续学习重点】
void mine_area_init(char mine_area[][COL]);
    */
    memset(mine_ui, '*', ROW * COL);
}

void mine_area_init(char mine_area[][COL])
{
    // 整个雷区所有的元素位置都是字符 '0'
    memset(mine_area, '0', ROW * COL);

    /*
    当前函数的功能是设置相关的随机数原则 time(0) 是
    随机数种子因素，对应当前时间，单位可以认为是毫米
    */
    srand(time(0));

    /**
     * 行下标变量
     */
    int row_index = 0;
    /**
     * 列下标变量
     */
    int col_index = 0;
    /**
     * 当前布雷成功的次数，因为 row_index 和 col_index 都需要通过
     * 随机数生成，有可能会导致出现同一个位置重复布雷情况，利用
     * current_mine_count 记录布雷成功次数
     */
    int current_mine_count = 0;

    /*
    如果地雷布置成功的次数 不等于 当前雷区限制的地雷总数，循环继续
    */
    while (current_mine_count != MINE_COUNT)
    {
        row_index = rand() % 10;
        col_index = rand() % 10;

        cout << "row_index : " << row_index << ", col_index : " << col_index << endl;
        // 如果对应下标位置在真实雷区数组中不是地雷
        if (mine_area[row_index][col_index] != '#')
        {
            /*
            首先完成
                1. 真实雷区数组对应下标位置进行赋值 '#' 操作，表示为地雷
                2. 布置成功的地雷个数 += 1
            */
            mine_area[row_index][col_index] = '#';
            current_mine_count += 1;

            /*
            将新放置地雷的周边 8 个元素位置进行 += 1 操作
            以下情况不做任何处理
                1. 周边位置为地雷
                2. 超出有效的雷区范围
            */
#if 0
            for (int i = row_index - 1; i <= row_index + 1; i++)
            {
                for (int j = col_index - 1; j <= col_index + 1; j++)
                {
                    if (i < 0 || j < 0 || i > ROW - 1 || j > COL - 1 || '#' == mine_area[i][j])
                    {
                        continue;
                    }
                    else
                    {
                        mine_area[i][j] += 1;
                    }
                }
            }
#endif
#if 1
            for (int i = (row_index - 1 >= 0 ? row_index - 1 : 0);
                 i <= (row_index + 1 > ROW - 1 ? ROW - 1 : row_index + 1);
                 i++)
            {
                cout << "i : " << i << endl;

                for (int j = (col_index - 1 >= 0 ? col_index - 1 : 0);
                     j <= (col_index + 1 > COL - 1 ? COL - 1 : col_index + 1);
                     j++)
                {
                    cout << "j : " << j << endl;

                    if (mine_area[i][j] != '#')
                    {
                        mine_area[i][j] += 1;
                    }
                }
            }
#endif
        }
    }
}

void show_mine_ui(char mine_ui[][COL])
{
    cout << "   1 2 3 4 5 6 7 8 9 10" << endl;

    for (int i = 0; i < ROW; i++)
    {
        if (i < 9)
        {
            cout << ' ' << i + 1 << ' ';
        }
        else
        {
            cout << i + 1 << ' ';
        }

        for (int j = 0; j < COL; j++)
        {
            cout << mine_ui[i][j] << ' ';
        }

        cout << endl;
    }
}

int explore_mine_area(char mine_ui[][COL],
                      char mine_area[][COL],
                      int row_index,
                      int col_index)
{
    /*
    判断用户提供的数据是否合法
    */
    if (row_index < 1 || row_index > ROW || col_index < 1 || col_index > COL)
    {
        cout << "用户提供下标数据不合法！" << endl;
        return 0;
    }

    /*
    用户提供的下标数据进行二次处理，符合数组下标要求
    */
    row_index -= 1;
    col_index -= 1;

    /*
    标记变量，用于记录当前用户探索的雷区的情况
        如果探索失败，flag 赋值为 0，如果探索成功 flag 依然为 1
    */
    int flag = 1;

    if ('#' == mine_area[row_index][col_index])
    {
        // 如果是地雷，flag 重新赋值为 0
        flag = 0;
    }
    else
    {
        // 如果不是地雷，将真实雷区对应的数据，赋值给当前的用户界面对应下标位置
        mine_ui[row_index][col_index] = mine_area[row_index][col_index];
    }

    return flag;
}

int mark_mine(char mine_ui[][COL],
              char mine_area[][COL],
              int row_index,
              int col_index)
{
    /*
    判断用户提供的数据是否合法
    如果用户指定下标位置非星号加密区域，无法进行标记操作，照样返回 -1
    */
    if (row_index < 1 || row_index > ROW || col_index < 1 || col_index > COL 
        || mine_ui[row_index - 1][col_index - 1] != '*')
    {
        cout << "用户提供下标数据不合法！" << endl;
        return -1;
    }

    // 对用户提供的下标数据进行二次处理
    row_index -= 1;
    col_index -= 1;

    // 用户界面对应下标位置直接赋值 'F' 
    mine_ui[row_index][col_index] = 'F';

    /*
    在真实雷区数组中，用户指定下标位置是一个地雷，当前 return 结果为 1
    如果不是地雷，return 结果为 0，满足当前函数声明要求的返回结果
    */
    return '#' == mine_area[row_index][col_index];

}